﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using Pixysoft.Framework.XSchEmA.Entity;
using Pixysoft.Framework.XSchEmA.Aspect;
using Pixysoft.Framework.XSchEmA.Hinter;

namespace Pixysoft.Framework.XSchEmA.Verifier
{
    partial class ColumnVerifier :  IColumnVerifier
    {
        private string msg;
        private ColumnVerifier() { }
        private static ColumnVerifier instance;
        public static ColumnVerifier Instance
        {
            get
            {
                lock (typeof(ColumnVerifier))
                {
                    if (instance == null)
                        instance = new ColumnVerifier();
                    return instance;
                }
            }
        }

        /// <summary>
        /// 新建字段使用
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="myTable">My table.</param>
        /// <param name="myColumn">My column.</param>
        /// <returns></returns>
        public bool VerifyColumnName(string input, ISchemaAspect aspect, DatabaseSchema database, TableSchema table)
        {
            input = input.ToUpper().Trim();

            if (!aspect.IsValidName(input))
            {
                msg = "不合法命名";
                return false;
            }

            foreach (ColumnSchema tcolumn in table.Columns)
            {
                if (tcolumn.ColumnName == input)
                {
                    msg = "字段名重复";
                    return false;
                }
            }
            return true;
        }
        /// <summary>
        /// 修改字段使用
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="myTable">My table.</param>
        /// <param name="myColumn">My column.</param>
        /// <returns></returns>
        public bool VerifyColumnRename(string input, ISchemaAspect aspect, DatabaseSchema database, TableSchema table, ColumnSchema column)
        {

            input = input.ToUpper().Trim();

            if (input == column.ColumnName)
            {
                msg = "字段名重复";
                return false;
            }

            if (!aspect.IsValidName(input))
            {
                msg = "不合法命名";
                return false;
            }

            foreach (ColumnSchema tcolumn in table.Columns)
            {
                if (tcolumn == column)
                    continue;

                if (tcolumn.ColumnName == input)
                    if (input == column.ColumnName)
                    {
                        msg = "字段名重复";
                        return false;
                    }
            }
            return true;
        }
        /// <summary>
        /// 根据数据实体和输入验证myColumn的字段类型
        /// 字段名/特殊唯一字段（包括外键的关系）
        /// </summary>
        /// <param name="input">The input.</param>
        /// 
        /// 
        /// <returns></returns>
        public bool VerifyDatatype(DataTypeSchema input, ISchemaAspect aspect, DatabaseSchema database, TableSchema table, ColumnSchema column)
        {
            input.Inspection();


            if (!aspect.IsValidDataType(input))
            {
                msg = "字段类型非法";
                return false;
            }

            if (!SmartHinter.Instance.GetDataTypeList(aspect, database, table, column).Contains(input.DataType))
            {
                msg = "字段类型非法";
                return false;
            }

            return true;
        }
        /// <summary>
        /// 验证是否非空
        /// 主键必须notnull
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="myColumn">My column.</param>
        /// <returns></returns>
        public bool VerifyIsNullable(bool input, DatabaseSchema database, TableSchema table, ColumnSchema column)
        {
            if (database.IsPrimaryKey(column) && input)
            {
                msg = "主键必须为非空";
                return false;
            }

            return true;
        }
        /// <summary>
        /// 验证主键名的修改
        /// 相同表主键名一致
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="aspect">The aspect.</param>
        /// <param name="database">The database.</param>
        /// <param name="table">The table.</param>
        /// <returns></returns>
        public bool VerifyIndexName(string input, ISchemaAspect aspect, DatabaseSchema database)
        {
            input = input.ToUpper().Trim();

            if (input.Trim() == "")
            {
                msg = "约束名非法";
                return false;
            }

            if (!aspect.IsValidName(input))
            {
                msg = "约束名非法";
                return false;
            }

            if (database.GetUniqueByName(input) != null)
            {
                msg = "存在相同的约束名";
                return false;
            }

            if (database.GetIndexByName(input) != null)
            {
                msg = "存在相同的约束名";
                return false;
            }

            if (database.GetPrimaryKeyByName(input) != null)
            {
                msg = "存在相同的约束名";
                return false;
            }

            if (database.GetForeignKeyByName(input) != null)
            {
                msg = "存在相同的约束名";
                return false;
            }

            return true;
        }
        /// <summary>
        /// 验证主键名的修改
        /// 相同表主键名一致
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="aspect">The aspect.</param>
        /// <param name="database">The database.</param>
        /// <param name="table">The table.</param>
        /// <returns></returns>
        public bool VerifyPkName(string input, ISchemaAspect aspect, DatabaseSchema database)
        {
            return VerifyIndexName(input, aspect, database);
        }
        /// <summary>
        /// Verifies the name of the pk.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="aspect">The aspect.</param>
        /// <param name="database">The database.</param>
        /// <returns></returns>
        public bool VerifyFkName(string input, ISchemaAspect aspect, DatabaseSchema database)
        {
            return VerifyIndexName(input, aspect, database);
        }
        /// <summary>
        /// 验证外键表的修改
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="myTable">My table.</param>
        /// <param name="myColumn">My column.</param>
        /// <returns></returns>
        public bool VerifyFkIndexName(string input, DatabaseSchema database, TableSchema fTable, List<ColumnSchema> fColumns)
        {
            input = input.ToUpper().Trim();

            IConstraintSchema cons = database.GetConstraint(input);

            if (cons == null)
                return false;

            return SmartHinter.Instance.GetForeignConstraintList(database, fTable, fColumns).Contains(cons);
        }
        /// <summary>
        /// Changes the default value.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="aspect">The aspect.</param>
        /// <param name="column">The column.</param>
        /// <returns></returns>
        public bool VerifyDefaultValue(string value, ISchemaAspect aspect, ColumnSchema column)
        {
            if (value.Trim() == "")
                return true;

            string tmpValue = aspect.ValidateDefaultValue(value, column.DataType);
            return value == tmpValue;
        }

        public string Message
        {
            get { return msg; }
        }
    }
}
